/**
 * 通用扫码回车延迟处理工具
 * 解决PDA扫码器输入过程中提前触发回车事件的问题
 */

export class ScanHandler {
  constructor(options = {}) {
    // 配置选项
    this.scanDelay = options.scanDelay || 300; // 扫描延迟时间(毫秒)
    this.maxConsecutiveEnters = options.maxConsecutiveEnters || 5; // 最大连续回车次数
    this.enterTimeThreshold = options.enterTimeThreshold || 150; // 连续回车时间阈值(毫秒)
    this.minScanLength = options.minScanLength || 10; // 最小扫描长度
    this.stableWaitTime = options.stableWaitTime || 800; // 输入稳定等待时间(毫秒)
    
    // 内部状态
    this.scanBuffer = ''; // 扫描缓冲区
    this.scanBufferTimer = null; // 缓冲区定时器
    this.isProcessingScan = false; // 是否正在处理扫描
    this.lastInputTime = 0; // 最后一次输入时间
    this.consecutiveEnterCount = 0; // 连续回车计数
    this.lastEnterTime = 0; // 最后一次回车时间
    this.inputStabilityTimer = null; // 输入稳定性定时器
    
    // 回调函数
    this.onScanComplete = options.onScanComplete || (() => {});
    this.onScanError = options.onScanError || (() => {});
  }

  /**
   * 处理输入事件 - 只更新缓冲区，不触发分割
   * @param {string} value - 当前输入值
   */
  handleInput(value) {
    const now = Date.now();
    const trimmedValue = value.trim();
    
    // 只更新缓冲区和时间，不设置任何定时器
    this.lastInputTime = now;
    this.scanBuffer = trimmedValue;
  }

  /**
   * 处理回车确认事件 - PDA的最后一个回车触发分割
   * @param {string} value - 当前输入值
   */
  handleConfirm(value) {
    if (this.isProcessingScan) {
      return; // 如果正在处理，忽略新的回车
    }
    
    const now = Date.now();
    const trimmedValue = value.trim();
    
    // 确保缓冲区有内容（防止第一次扫描时缓冲区为空）
    if (!this.scanBuffer || this.scanBuffer.trim() !== trimmedValue) {
      this.scanBuffer = trimmedValue;
    }
    this.lastInputTime = now;
    
    // 清除所有存在的定时器
    if (this.scanBufferTimer) {
      clearTimeout(this.scanBufferTimer);
      this.scanBufferTimer = null;
    }
    if (this.inputStabilityTimer) {
      clearTimeout(this.inputStabilityTimer);
      this.inputStabilityTimer = null;
    }
    
    // 验证扫描数据有效性
    if (!trimmedValue) {
      return; // 空值不处理
    }
    
    // PDA扫码器特性：最后的回车就是扫码完成信号
    // 但要等待一个短暂延时确保输入稳定
    this.scanBufferTimer = setTimeout(() => {
      this.processCompleteScan();
    }, 100); // 只需要100ms的短暂延时
  }

  /**
   * 处理完整的扫描数据
   */
  processCompleteScan() {
    if (this.isProcessingScan) {
      return;
    }
    
    this.isProcessingScan = true;
    const scanValue = this.scanBuffer.trim();
    
    // 清理状态
    this.clearBuffer();
    
    try {
      // 调用完成回调
      this.onScanComplete(scanValue);
    } catch (error) {
      this.onScanError(error, scanValue);
    } finally {
      // 重置处理状态
      this.isProcessingScan = false;
    }
  }

  /**
   * 清理缓冲区和所有定时器
   */
  clearBuffer() {
    this.scanBuffer = '';
    if (this.scanBufferTimer) {
      clearTimeout(this.scanBufferTimer);
      this.scanBufferTimer = null;
    }
    if (this.inputStabilityTimer) {
      clearTimeout(this.inputStabilityTimer);
      this.inputStabilityTimer = null;
    }
  }

  /**
   * 重置所有状态
   */
  reset() {
    this.clearBuffer();
    this.isProcessingScan = false;
    this.lastInputTime = 0;
    this.consecutiveEnterCount = 0;
    this.lastEnterTime = 0;
  }

  /**
   * 销毁处理器，清理所有定时器
   */
  destroy() {
    this.reset();
    this.onScanComplete = null;
    this.onScanError = null;
  }
}

/**
 * 解析订单扫码数据
 * 格式: 订单No-01实装机ID实装面
 * 例如: NEW001-01NEW_MT0011
 * @param {string} scanValue - 扫描值
 * @returns {Object} 解析结果
 */
export function parseOrderScanData(scanValue) {
  if (!scanValue || typeof scanValue !== 'string') {
    return {
      success: false,
      error: '扫描值为空或格式错误'
    };
  }

  // 查找-01分隔符（必须包含-符号）
  const separatorIndex = scanValue.indexOf('-01');
  
  if (separatorIndex === -1 || separatorIndex < 3) { // 订单号至少3个字符
    return {
      success: false,
      error: '扫描数据格式不正确，缺少-01分隔符'
    };
  }

  // 分割数据
  const orderNo = scanValue.substring(0, separatorIndex);
  const remainingPart = scanValue.substring(separatorIndex + 3); // +3 跳过'-01'

  if (!orderNo || !remainingPart || remainingPart.length < 2) {
    return {
      success: false,
      error: '扫描数据格式不正确，订单号或机器信息缺失'
    };
  }

  // 解析机器ID和面
  // 最后一个字符是面，其余是机器ID
  // 处理实装面前可能存在的点号，需要忽略
  let surface = remainingPart.slice(-1);
  let machineId = remainingPart.slice(0, -1);
  
  // 如果实装面前有点号，需要将点号归入机器ID部分
  if (machineId.endsWith('.')) {
    // 检查倒数第二个字符是否为点号
    if (remainingPart.length >= 2 && remainingPart.slice(-2, -1) === '.') {
      // 实装面应该是点号后面的字符，机器ID不包含最后的点号
      surface = remainingPart.slice(-1);
      machineId = remainingPart.slice(0, -2);
    }
  }

  if (!machineId || !surface) {
    return {
      success: false,
      error: '扫描数据格式不正确，机器ID或面信息缺失'
    };
  }

  return {
    success: true,
    data: {
      orderNo,
      machineId,
      surface,
      originalValue: scanValue
    }
  };
}

/**
 * 创建焦点管理器
 * 用于统一管理输入框焦点状态
 */
export class FocusManager {
  constructor() {
    this.currentFocusField = null;
    this.pendingFocusField = null;
    this.focusDelay = 100; // 焦点切换延迟
  }

  /**
   * 设置焦点到指定字段
   * @param {string} fieldName - 字段名
   * @param {Function} setFocusCallback - 设置焦点的回调函数
   * @param {number} delay - 延迟时间(可选)
   */
  setFocus(fieldName, setFocusCallback, delay = this.focusDelay) {
    // 如果当前已有待处理的焦点设置，取消它
    if (this.pendingFocusField) {
      clearTimeout(this.pendingFocusField);
    }

    // 先清除当前焦点
    if (setFocusCallback) {
      setFocusCallback(null);
    }
    
    // 延迟设置新焦点
    this.pendingFocusField = setTimeout(() => {
      if (setFocusCallback) {
        setFocusCallback(fieldName);
        this.currentFocusField = fieldName;
      }
      this.pendingFocusField = null;
    }, delay);
  }

  /**
   * 清除所有焦点
   * @param {Function} setFocusCallback - 设置焦点的回调函数
   */
  clearFocus(setFocusCallback) {
    if (this.pendingFocusField) {
      clearTimeout(this.pendingFocusField);
      this.pendingFocusField = null;
    }
    
    if (setFocusCallback) {
      setFocusCallback(null);
    }
    this.currentFocusField = null;
  }

  /**
   * 销毁管理器
   */
  destroy() {
    if (this.pendingFocusField) {
      clearTimeout(this.pendingFocusField);
    }
    this.currentFocusField = null;
    this.pendingFocusField = null;
  }
}